#ifndef __USERS_H__
#define __USERS_H__
#include "stdint.h"
#include "osal.h"

/* 密钥类型/用户类型/eventSource */
#define USERS_TYPE_PWD              0X00 //密码类型
#define USERS_TYPE_PLOY_PWD			0x01 //策略密码（降本项目策略密钥独立数量）
#define USERS_TYPE_CARD             0X03 //卡片类型
#define USERS_TYPE_FPT              0X04 //指纹类型
#define USERS_TYPE_FACE		   	    0X07 //人脸类型
#define USERS_TYPE_APP              0X08 //APP开启类型
#define USERS_TYPE_MACHINE_KEY      0X09 //机械钥匙类型（室内机械方式开锁、室外机械钥匙开锁）
#define USERS_TYPE_OPEN_KEY         0X0A //室内OPEN键开锁
#define USERS_TYPE_TOUCH_HANDLE     0X0B //感应把手开门
#define USERS_TYPE_PVN				0X0C //掌静脉
#define USERS_TYPE_EVIDENCE			0X0D //凭证
#define USERS_TYPE_UNKNOW			0XFF //不确定
#define EVENT_SOURCE_MSENSOR        0X0A //门磁传感器（当eventType为传感器类型时）
#define EVENT_SOURCE_XIAODU         0X10 //小度智能屏
#define EVENT_SOURCE_MAOJING        0x11 //猫精智能屏
#define USERS_TYPE_FVN              0X12 //指静脉类型
#define USERS_TYPE_KEY              0X13 //按键类型--开锁,关锁
#define USERS_TYPE_TEMPORARY_PWD    0X14 //临时密码--待增加该类型
#define USERS_TYPE_BLE              0X15 //蓝牙开锁
#define USERS_TYPE_ADMIN_PWD        0X16 //管理员密码开锁

//关锁类型
//上报关锁事件(0x8051) 关锁方式
#define LOCKED_INDOOR             0x00       // 门内关锁
#define LOCKED_MANUAL             0x01       // 旋钮关锁 
#define LOCKED_OUTDOOR            0x02       // 门外关锁
#define LOCKED_TIMING             0x03       // 定时关锁 
#define LOCKED_ROMOTE             0x04       // 远程关锁

/* 密钥编号/用户编号/userID（这里是特殊密钥编号） */
#define USERS_ID_MACHINE_KEY        100 //机械钥匙（机械方式）开锁编号
#define USERS_ID_REMOTE             101 //远程开锁编号
#define USERS_ID_SIGNAL             102 //一键开锁编号（室内OPEN键开锁编号）
#define USERS_ID_APP                103 //APP开锁编号
#define USERS_ID_BLE                104 //ble自动开锁编号
#define USERS_ID_TOUCH_HANDLE       106 //感应把手开锁编号
#define USERS_ID_ONCE		      	252 //一次性密码编号
#define USERS_ID_OFFLINE            250 //离线密码功能
#define USERS_ID_EXPERIENCE         251 //体验模式编号
#define USERS_ID_RFEEZE             253 //冻结状态
#define USERS_ID_ADMIN              254 //管理员开锁编号（管理指纹、管理密码）（反锁状态下管理员密码可以开门）
#define USERS_ID_SYSLOCK            249 //凭证试开

/* 密钥属性 */
#define USERS_ATTR_FOREVER          0X00 //永久密钥
#define USERS_ATTR_PLOY             0X01 //时间策略
#define USERS_ATTR_URGENT           0X02 //胁迫(紧急)
#define USERS_ATTR_ADMIN            0X03 //管理员
#define USERS_ATTR_NOT              0X04 //无权限
#define USERS_ATTR_WEEK				0X05 //周策略
#define USERS_ATTR_ONCE             0XFE //一次性
#define USERS_ATTR_ONCE_PLOY        0XF0 //一次性+策略（固定10分钟）

/* Users_Verify接口的特殊返回值 */
#define VERIFY_ADMIN_OK             USERS_ID_ADMIN     //管理员验证成功
#define	VERIFY_ERROR                -1     //验证错误
#define	ACTIVATION_OK               -2     //激活成功
#define	NOT_ACTIVATION              -3     //门锁未激活
#define VERIFY_DUAL_OFFSET          1000   //双重验证模式下，首次验证ID号的偏移值

/* 密钥删除失败错误码 */
#define USERS_DEL_ERR				-1		//删除失败

/* 消息上报ID号 */
#define USERS_MSG_ID_URGENT			-1		//胁迫密码开锁

//最大密码长度
#ifdef  KOS_PARAM_USERS_PWD_MAX_LEN
#define PWD_LEN_MAX					KOS_PARAM_USERS_PWD_MAX_LEN
#else
#define PWD_LEN_MAX					10
#endif
//最大凭证长度
#define EVIDENCE_LEN_MAX	8

/* 密钥添加结果 */
typedef enum
{
	ADD_ONCE_OK,              //添加密码时，第一次输入OK
	ADD_SUCCESS,              //添加密钥成功
	ADD_ERROR,                //添加失败
	ADD_ERR_TOO_SIMPLE,       //密码太简单
	ADD_ERR_NOT_SAME,         //两次密码不一样
	ADD_ERR_EXISTS,           //密钥已存在
	ADD_ERR_RANGE,            //密码长度超出范围
	ADD_ERR_CARD_EXISTS,      //卡片已存在
	ADD_ERR_KEYS_LIB_IS_FULL, //密码库已满
	ADD_RES_UNKNOW,           //添加结果未知（可能正在添加中...）
    ADD_ERR_DARD_ILLEGAL,     //非法卡片
    ADD_ERR_FACE_CLOSE,       //人脸功能已关闭
    ADD_ERR_FACE_OTA_MODE,    //人脸正在升级
}UsersAddRes_enum_t;

/* 密钥编号的状态 */
typedef enum
{
	USERS_NUMBER_ERROR,   //错误编号
	USERS_NUMBER_EXISTED, //编号已占用
	USERS_NUMBER_IDLE,    //编号未占用
}UsersNumStatus_enum_t;

/* Users组件消息类型 */
typedef struct 
{
    int16_t ID;           //消息ID号
	uint8_t keysNum;	  //密钥编号
}UsersMsg_t;

#pragma pack(1)
typedef struct 
{
	uint8_t  week;     //钥匙策略：周几生效（为0表示当前策略类型为年月日策略）
	uint32_t stime;    //钥匙策略：起始时间
	uint32_t etime;    //钥匙策略：结束时间
}UserPloy_stu_t;

typedef struct 
{
    uint8_t  attr;     		//钥匙属性：永久、一次性、策略……
	UserPloy_stu_t ploy;	//钥匙策略
}UserAttrPloy_stu_t;

typedef struct users
{
    uint8_t   attr;        //密钥属性
    uint8_t  week;     //钥匙策略：周几生效（为0表示当前策略类型为年月日策略）
	uint32_t stime;    //钥匙策略：起始时间
	uint32_t etime;    //钥匙策略：结束时间
    uint32_t  creatTime;   //创建时间

}KeyList_stu_t;            
#pragma pack()

static int32_t Users_Verify(uint8_t *pData, uint8_t len, uint8_t dualFlag, uint8_t keysType, uint8_t asterisk, int16_t time_zone);//验证用户
static UsersAddRes_enum_t Users_Add(uint8_t keysType, uint8_t keysNum, uint8_t *pData, uint8_t len, uint8_t keysPloyAttr, FlagStatus dualFlag);//添加用户
static int32_t Users_Del(uint8_t keysType, uint8_t keysNum, uint8_t *data, uint8_t len);  //删除用户(data为NULL时删除全部用户)
static ErrorStatus Users_DelOnce(uint8_t *keysType, uint8_t *keysNum); //删除一次性用户
static uint8_t Users_MatchKeysLibrary(uint8_t keysType, uint8_t *pData, uint8_t len, uint8_t opt, void *keys_data);//获取密钥数据
static uint8_t Users_GetValidId(uint8_t keysType);//获取有效的用户编号
static uint8_t Users_GetQty(uint8_t keysType, uint8_t opt);//获取有效的用户数量
static ErrorStatus Users_GetList(KeyList_stu_t keyList[], uint8_t keysType);//获取秘钥列表
static ErrorStatus Users_CheckAdmin(uint8_t keysType);//检查管理密码
static ErrorStatus Users_GetAttrPloy(uint8_t keysType, uint8_t keysNum, UserAttrPloy_stu_t *pAttrPloy);//获取密钥策略
static ErrorStatus Users_SetAttrPloy(uint8_t keysType, uint8_t keysNum, uint8_t attr,UserPloy_stu_t *pPloy);//设置密钥策略

static ErrorStatus Users_SetSafeMode(FlagStatus flag);//设置安全模式
static FlagStatus Users_GetSafeMode(void);//获取安全模式
static ErrorStatus Users_SetActiveCode(uint8_t activeCode[]);//设置激活码
static ErrorStatus Users_GetActiveCode(uint8_t activeCode[]);//获取激活码
static ErrorStatus Users_SetActiveCodeStatus(uint8_t status);//设置激活码状态
static ErrorStatus Users_SetAteFlag(ErrorStatus flag);//设置产测标志
static ErrorStatus Users_SetKeysQty(uint8_t keysType, uint16_t keysQty);//设置密钥数量
static uint16_t Users_GetKeysQty(uint8_t keysType);//设获取密钥数量
static ErrorStatus Users_SetUrgent(FlagStatus Flag);//设置胁迫密码报警功能开关
static FlagStatus Users_GetUrgent(void);
static ErrorStatus Users_OfflinePwd_CreateFactor(uint8_t *pFactor, uint8_t opt, uint8_t eSN[], uint8_t eSNLen);
static ErrorStatus Users_OfflinePwd_SaveRandom(void);
static ErrorStatus Users_AdminPwdIsEasy(void);
static ErrorStatus Users_IsLockActived(uint8_t *code);
static ErrorStatus Users_OfflinePwdVerifySha256(char *str_pwd_sha256, uint32_t timestamp);
static UsersNumStatus_enum_t Users_KeyNumIsExist(uint8_t keysType, uint8_t Num);
static uint8_t Users_CardIsExist(uint8_t* pdata, uint8_t len);
static uint8_t User_GetIsModifyAdminPwd(void);
static uint8_t Users_GetKeysLen(uint8_t *pData, uint8_t maxLen);
static UsersAddRes_enum_t Users_ModifyPassword(uint8_t *pData, uint8_t keysNum);
static uint8_t Users_ReadKeysNumStatus(uint8_t keysType, uint8_t keysNum);
static ErrorStatus Users_ReadKeys(uint8_t keysType, uint8_t keysId, void *pData);
static ErrorStatus Users_ReadAdminPassword(void *pData);
static uint8_t User_GetKeyTypeQty(uint8_t*pData);
static uint8_t Users_updata_keys_status(uint8_t keysType, uint8_t evidId, uint8_t status, uint8_t updataType);

#endif /* __USERS_H__ */
